'''
    This file is part of Ognom Keeper.

    Ognom Keeper is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Ognom Keeper is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Ognom Keeper.  If not, see <http://www.gnu.org/licenses/>.


    Copyright(C) 2009 Viktor Vestberg
'''

try:
    from handlers import *
    from parts import *
    from factory import *
except ImportError, err:
    print str("couldn't load module. %s" % (err))
      
class StateManager:
    """A way to administrate the different states"""
    def __init__(self):
        self.stateList = []
        self.currentState = State()
        self.fallBackState = self.currentState
    def setState(self, state):
        self.currentState.stop()
        self.currentState = state
        self.currentState.start()
    def setFallBackState(self, state):
        self.fallBackState = state
    def runFallBackState(self):
        self.setState(self.fallBackState)
    # Add a list of states
    def addStates(self, states):
        for state in states:
            self.stateList.append(state)
            state.setParent(self)
            state.init()

class State:
    """"Abstract class for all the states, its just there so code wont have to be rewritten"""
    def __init__(self):
        self.handlers = []
        self.parent = None  # The StateManager, weird name for it I know
        self.manager = Manager() # manages all the handlers
    def init(self):
        pass
    def setParent(self, parent):
        self.parent = parent
    def setActive(self):
        self.parent.setState(self)      # This makes this state the one that is currently running
    def stop(self):
        self.manager.stop()
    def start(self):
        self.manager.start()
    def update(self):
        self.manager.update()       # This should be called every frame/tick

class RunGamestate(State):
    def init(self):
        self.input.makeKeypart(pygame.K_ESCAPE, [self.parent.runFallBackState])
    def __init__(self):
        self.manager       = Manager()
        self.input         = Input()
        self.renderer      = Renderer()
        self.text          = Text()
        self.bgHandler     = BgHandler()
        self.physics       = Physics()
        self.entityHandler = EntityHandler()
        self.camera        = Camera()
        self.music         = MusicHandler()
        self.menu          = Menu(self.text, self.input)
        self.playerFactory = PlayerFactory(self.entityHandler, self.renderer, self.physics, self.input)
        self.wallFactory = WallFactory(self.entityHandler, self.renderer, self.physics)
        self.wallAdder = WallAdder(self.wallFactory)
        self.levelLoader = LevelLoader(self.wallFactory, self.playerFactory)
        
        self.levelLoader.addUpdaters([self.renderer, self.bgHandler, self.camera, self.wallAdder, self.playerFactory])
        self.manager.addHandler([self.entityHandler, self.input, self.bgHandler, self.menu,
                                self.renderer, self.camera, self.text, self.wallAdder, self.music, self.physics ])

        self.music.addFolder('game_music')
        
        self.input.makeMouseKeypart(1, [self.wallAdder.addMousePos])
        self.input.makeMouseKeypart(3, [self.wallAdder.addWall])
        #self.input.makeKeypart(pygame.K_PAUSE, [self.physics.pause])

        self.text.makeText('Extra lives:', (15,10), 14, [255,255,255])
        
        self.input.makeKeypart(pygame.K_l, [self.playerFactory.makePlayer])
        self.input.makeKeypart(pygame.K_LEFT, [self.camera.moveLeft], None, True)
        self.input.makeKeypart(pygame.K_RIGHT, [self.camera.moveRight], None, True)
        self.input.makeKeypart(pygame.K_UP, [self.camera.moveUp], None, True)
        self.input.makeKeypart(pygame.K_DOWN, [self.camera.moveDown], None, True)
                
class MenuState(State):
    def __init__(self):
        self.manager    = Manager()
        self.input      = Input()
        self.renderer   = Renderer()
        self.text       = Text()
        self.bgHandler  = BgHandler()
        self.music      = MusicHandler()
        self.menu       = Menu(self.text, self.input)
        
        self.manager.addHandler([self.menu, self.renderer, self.bgHandler, self.text,self.music, self.input])
        
        bgPic = load_image('menu_bg.png')[0]
        bgSurf = pygame.Surface(bgPic.get_size())
        self.text.makeText('Ognom Keeper', (20,400), 22, [255,255,255])
        
        self.renderer.setBgPicture(bgPic)
        self.renderer.setBgSurface(bgSurf)
        
        self.bgHandler.setBgSurface(bgSurf)
        self.bgHandler.setBgPicture(bgPic)
        
        self.music.addTrack('menu.ogg')

class HowToPlayState(State):
    def init(self):
        self.input.makeKeypart(pygame.K_ESCAPE, [self.parent.runFallBackState])
    def __init__(self):
        self.manager    = Manager()
        self.input      = Input()
        self.renderer   = Renderer()
        self.text       = Text()
        self.bgHandler  = BgHandler()
        self.menu       = Menu(self.text, self.input)
        
        self.manager.addHandler([self.menu, self.renderer, self.bgHandler, self.text, self.input])
        
        bgPic = load_image('howtoplay.png')[0]
        bgSurf = pygame.Surface(bgPic.get_size())
        
        self.renderer.setBgPicture(bgPic)
        self.renderer.setBgSurface(bgSurf)
        
        self.bgHandler.setBgSurface(bgSurf)
        self.bgHandler.setBgPicture(bgPic)
        
class FinishState(State):
    def init(self):
        self.input.makeKeypart(pygame.K_ESCAPE, [self.parent.runFallBackState])
    def __init__(self):
        self.manager    = Manager()
        self.input      = Input()
        self.renderer   = Renderer()
        self.text       = Text()
        self.bgHandler  = BgHandler()
        self.music      = MusicHandler()
        self.menu       = Menu(self.text, self.input)
        
        self.manager.addHandler([self.menu, self.renderer, self.bgHandler, 
                                self.text,self.music, self.input])
        
        bgPic = pygame.Surface(pygame.display.get_surface().get_size())
        bgPic.fill([0,0,0])
        bgSurf = pygame.Surface(bgPic.get_size())
        
        self.renderer.setBgPicture(bgPic)
        self.renderer.setBgSurface(bgSurf)
        
        self.bgHandler.setBgSurface(bgSurf)
        self.bgHandler.setBgPicture(bgPic)
        self.music.addTrack('finish.ogg')
        self.text.makeText('Level Clear!', (75,80), 72)
        self.text.makeText('Score this level: ', (250,100), 20)
        self.text.makeText('Total score: ', (300,100), 20)

class HiScoreState(State):
    def init(self):
        self.input.makeKeypart(pygame.K_ESCAPE, [self.parent.runFallBackState])
    def __init__(self):
        self.manager    = Manager()
        self.input      = Input()
        self.renderer   = Renderer()
        self.text       = Text()
        self.bgHandler  = BgHandler()
        self.menu       = Menu(self.text, self.input)
        
        self.manager.addHandler([self.menu, self.renderer, self.bgHandler, self.text, self.input])
        
        bgPic = pygame.Surface(pygame.display.get_surface().get_size())
        bgPic.fill([0,0,0])
        bgSurf = pygame.Surface(bgPic.get_size())
        
        self.renderer.setBgPicture(bgPic)
        self.renderer.setBgSurface(bgSurf)
        
        self.bgHandler.setBgSurface(bgSurf)
        self.bgHandler.setBgPicture(bgPic)
        self.text.makeText('Top 10', (20,250), 52)
        self.toplist = []
        for i in range(10):
            text = self.text.makeText('', ((140+i*30),250), 15, [255,0,255])
            self.toplist.append(text)
        
    def updateList(self, list):
        number = 10
        if len(list) < 10: number = len(list)
        for i in range(number):
            score = list[i]
            self.toplist[i].data = score[1]+"              "+str(score[0])
            

class CompleteState(State):
    def init(self):
        self.input.makeKeypart(pygame.K_ESCAPE, [self.parent.runFallBackState])
    def __init__(self):
        self.manager    = Manager()
        self.input      = Input()
        self.renderer   = Renderer()
        self.text       = Text()
        self.bgHandler  = BgHandler()
        self.music      = MusicHandler()
        self.menu       = Menu(self.text, self.input)
        self.enterText  = EnterText(self.text, self.input)
        
        self.manager.addHandler([self.menu, self.renderer, self.bgHandler, 
                                self.text,self.music, self.input, self.enterText])
        
        bgPic = pygame.Surface(pygame.display.get_surface().get_size())
        bgPic.fill([0,0,0])
        bgSurf = pygame.Surface(bgPic.get_size())
        
        self.renderer.setBgPicture(bgPic)
        self.renderer.setBgSurface(bgSurf)
        
        self.bgHandler.setBgSurface(bgSurf)
        self.bgHandler.setBgPicture(bgPic)
        self.music.addTrack('finish.ogg')

        self.overText = self.text.makeText('You have completed', (45,70), 42)
        self.text.makeText('the game!', (130,220), 42)
        self.text.makeText('Total score: ', (250,220), 20)
        self.text.makeText('Enter your name: ', (330,110), 20)
        self.name = self.enterText.makePart('', (330,400), 20, (255,0,255))
    def setGameOverText(self):
        self.overText.data = '   You have failed'
        self.music.setTrack('gameover.ogg')
    def setFinishText(self):
        self.overText.data = 'You have completed'
        self.music.setTrack('finish.ogg')
        

        